home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d16 / winvn060.arc / WINVN.C < prev    next >
C/C++ Source or Header  |  1991-07-01  |  16KB  |  491 lines

  1. /*  WinVn.c
  2.  *
  3.  *  This program is a visual Usenet news reader for Microsoft Windows.
  4.  *  It bears a vague similarity to the Unix program "vn"; hence the
  5.  *  name WINVN.
  6.  *
  7.  *  WinVN talks NNTP (Network News Transport (?) Protocol) to a news
  8.  *  server, which must be running the NNTP program.  (The source for
  9.  *  a unix implementation of NNTP is readily and apparently freely
  10.  *  available.)
  11.  *
  12.  *  WINVN currently only reads articles; it does not allow posting
  13.  *  or mailing.  Posting will be implemented when I get around to it;
  14.  *  the delay is due to the need to first implement an authentication
  15.  *  scheme so we know the poster is accurately identified.
  16.  *
  17.  *  For more information, see WINVN.WRI and WVDOC.C.
  18.  *
  19.  *  Mark Riordan    September - October 1989    riordanmr@clvax1.cl.msu.edu
  20.  *  1100 Parker  Lansing, MI  48912
  21.  */
  22.  
  23.  
  24. #define WINMAIN
  25. #include "windows.h"
  26. #include "WVglob.h"
  27. #include "WinVn.h"
  28. #ifndef MAC
  29. #include "winundoc.h"
  30. #endif
  31. #include "ctype.h"
  32.  
  33. char *CommStrtoID(char *, int *, int *, char *);
  34.  
  35. /*--- function WinMain -----------------------------------------------
  36.  *
  37.  *  Main program for WinVN.
  38.  *  Initialize, then execute main loop.
  39.  *
  40.  *    Entry    hInstance      is a handle to this instance of execution
  41.  *                            of this program.
  42.  *             hPrevInstance  is a handle to a previous instance
  43.  *                            of execution of this program (usually
  44.  *                            0, i.e., none.  Few people would have
  45.  *                            two copies of WinVN running simultaneously.)
  46.  *             lpCmdLine      points to the command line--currently
  47.  *                            not used.  (Not to useful for Windows programs.)
  48.  *             nCmdShow       is a flag indicating that the main window
  49.  *                            should be displayed.  (Fairly worthless.)
  50.  */
  51.  
  52. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  53. HANDLE hInstance;
  54. HANDLE hPrevInstance;
  55. LPSTR lpCmdLine;
  56. int nCmdShow;
  57. {
  58.    HWND hWnd;
  59.    HDC hDC;
  60.  
  61.    if (!hPrevInstance)
  62.       if (!WinVnInit(hInstance))
  63.          return (0);
  64. #ifndef MAC
  65.    hInst = hInstance;
  66. #endif
  67.  
  68.    /* Set up communications--serial or IP.                           */
  69.  
  70.    MRRInitComm();
  71.  
  72.    /* Initialize the document that will contain the list of          */
  73.    /* newsgroups.  This will be the main window.                     */
  74.  
  75.    InitDoc(&NetDoc,(HWND) 0,(TypDoc *) NULL,DOCTYPE_NET);
  76.  
  77.    /* Create and display the main window.  At first, the window      */
  78.    /* just has an initialization message in it.                      */
  79.  
  80.    hWnd = CreateWindow("WinVn",
  81.         "WinVN -- Usenet News Reader",
  82.         WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  83.         0,    /* Initial X position */
  84.         0,    /* Initial Y position */
  85.         (int) (xScreen * 7 / 20),  /* Initial X width */
  86.         (int) (yScreen * 3 / 8),  /* Initial Y height */
  87.         NULL,
  88.         NULL,
  89.         hInstance,
  90.         NULL);
  91.  
  92.    if (!hWnd)  return (0);
  93.  
  94.    hWndConf = hWnd;
  95.       NetDoc.hDocWnd = hWnd; /* mrr */
  96.  
  97.    MoreInit();
  98.  
  99. #ifndef MAC
  100.    ShowWindow(hWnd, nCmdShow);
  101. #endif
  102.    UpdateWindow(hWnd);
  103.    SendMessage(hWnd,WM_SIZE,0,0L);
  104.  
  105.    /* Read the NEWSRC file and display its contents in the           */
  106.    /* main window.                                                   */
  107.  
  108.    if(!ReadNewsrc()) {
  109.       MessageBox(hWndConf,"Cannot open the NEWSRC file.","Fatal error",MB_OK|MB_ICONHAND);
  110.       PostQuitMessage(0);
  111.    }
  112.    Initializing = INIT_ESTAB_CONN;
  113.    InvalidateRect(hWnd,NULL,FALSE);
  114.  
  115.    /* And now for the main loop, which appears in all Windows programs. */
  116.  
  117. #ifndef MAC
  118.    hAccel = LoadAccelerators(hInstance, "WinVNAccel");
  119. #endif
  120. #ifndef MAC
  121.    while(MainLoopPass());
  122.    return (MainMsg.wParam);
  123. #endif
  124. }
  125.  
  126. /* --- FUNCTION WinVnInit ---------------------------------------------
  127.  *
  128.  *    Initialize the program (first stage).
  129.  *    This routine does some initialization needed before the
  130.  *    creation of the main window.
  131.  *    I put off additional initialization until after the main
  132.  *    window is created.
  133.  *
  134.  *    Entry    hInstance   is a handle to the current instance of
  135.  *                         execution.
  136.  *
  137.  *    Exit     Window classes have been registered, and a small
  138.  *             amount of other window- and comm-related initialization
  139.  *             is done.
  140.  */
  141.  
  142. BOOL WinVnInit(hInstance)
  143. HANDLE hInstance;
  144. {
  145.    HANDLE hMemory;
  146. #ifndef MAC
  147.    PWNDCLASS pWndClass;
  148. #endif
  149.    char mesbuf[60], mesbuf2[60];
  150.    char buf[60];
  151.    char *errptr;
  152.    BOOL bSuccess;
  153.  
  154.    Initializing = INIT_READING_NEWSRC;
  155.    SaveNewsrc = TRUE;
  156.    CommLineLWAp1 = CommLineIn + MAXCOMMLINE;
  157.    LineHeight = 30;  /* kludge so Net window doesn't get divide-by-zero */
  158.  
  159. #ifndef MAC
  160.    szAppName = "WinVN";
  161.  
  162.    /* Read profile strings.   */
  163.  
  164.    UsingSocket = GetProfileInt(szAppName,"UseSocket",1);
  165.    GetProfileString(szAppName,"NNTPIPAddr","35.8.2.20",NNTPIPAddr,MAXNNTPSIZE);
  166.    NNTPPort = GetProfileInt(szAppName,"NNTPPort",1521 /*normally 119*/);
  167.    GetProfileString(szAppName,"CommString","COM1:9600,e,7",szCommString,MAXCOMMCHARS);
  168.    errptr = CommStrtoID(szCommString,&CommPortID,&CommParityID,pszCommSpeed);
  169.    if(errptr) {
  170.       strcpy(mesbuf,"Error parsing ");
  171.       strcat(mesbuf,szCommString);
  172.       MessageBox(hWndConf,errptr,mesbuf,MB_OK|MB_ICONEXCLAMATION);
  173.    }
  174.  
  175.    DoList = GetProfileInt(szAppName,"DoList",ID_DOLIST_ASK);
  176.  
  177.    GetProfileString(szAppName,"UserName","",UserName,MAILLEN);
  178.    GetProfileString(szAppName,"MailAddress","",MailAddress,MAILLEN);
  179.    GetProfileString(szAppName,"Organization","",Organization,MAILLEN);
  180.  
  181.  
  182.    FontSize = GetProfileInt(szAppName,"FontSize",0);
  183.    GetProfileString(szAppName,"FontFace","Helv",FontFace,32);
  184.    FontBold = GetProfileInt(szAppName,"FontBold",TRUE);
  185.    GetProfileString(szAppName,"NetUnSubscribedColor","200,60,150",buf,32);
  186.    NetUnSubscribedColor = StrToRGB(buf);
  187.    GetProfileString(szAppName,"GroupSeenColor","100,120,180",buf,32);
  188.    GroupSeenColor = StrToRGB(buf);
  189.    ViewNew = GetProfileInt(szAppName,"NewWndGroup",FALSE);
  190.    NewArticleWindow = GetProfileInt(szAppName,"NewWndArticle",FALSE);
  191.    SaveArtAppend = GetProfileInt(szAppName,"SaveArtAppend",TRUE);
  192.    ThumbTrack = GetProfileInt(szAppName,"ThumbTrack",TRUE);
  193.  
  194.    /* Create pointers to the dialog box functions, needed   */
  195.    /* for routine processing of dialog boxes.               */
  196.  
  197.    lpfnWinVnCommDlg =    MakeProcInstance(WinVnCommDlg, hInstance);
  198.    lpfnWinVnSaveArtDlg = MakeProcInstance(WinVnSaveArtDlg,hInstance);
  199.    lpfnWinVnFindDlg =    MakeProcInstance(WinVnFindDlg,hInstance);
  200.    lpfnWinVnAuthDlg =    MakeProcInstance(WinVnAuthDlg,hInstance);
  201.    lpfnWinVnDoListDlg =  MakeProcInstance(WinVnDoListDlg,hInstance);
  202.    lpfnWinVnPersonalInfoDlg = MakeProcInstance(WinVnPersonalInfoDlg,hInstance);
  203.    lpfnWinVnMiscDlg =    MakeProcInstance(WinVnMiscDlg,hInstance);
  204.    lpfnWinVnAppearanceDlg   = MakeProcInstance(WinVnAppearanceDlg,hInstance);
  205.  
  206.    xScreen = GetSystemMetrics(SM_CXSCREEN);
  207.    yScreen = GetSystemMetrics(SM_CYSCREEN);
  208. #else
  209.    xScreen = screenBits.bounds.right;
  210.    yScreen = screenBits.bounds.bottom - 20;
  211.    TEHCurrent = 0;
  212. #endif
  213.    CommDoc = &NetDoc;
  214.    Authorized = FALSE;
  215.  
  216. #ifndef MAC
  217.    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
  218.    pWndClass = (PWNDCLASS) LocalLock(hMemory);
  219.    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  220.    pWndClass->hIcon = LoadIcon(hInstance, (LPSTR) "winvn");
  221.    pWndClass->lpszMenuName = (LPSTR) "ConfMenu";
  222.    pWndClass->lpszClassName = (LPSTR) "WinVn";
  223.    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  224.    pWndClass->hInstance = hInstance;
  225.    pWndClass->style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  226.    pWndClass->lpfnWndProc = WinVnConfWndProc;
  227.  
  228.    bSuccess = RegisterClass(pWndClass);
  229.  
  230.    if(bSuccess) {
  231.       pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  232.       pWndClass->hIcon = LoadIcon(hInstance, (LPSTR) "wvgroup");
  233.       pWndClass->lpszMenuName = (LPSTR) "ViewMenu";
  234.       pWndClass->lpszClassName = (LPSTR) "WinVnView";
  235.       pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  236.       pWndClass->hInstance = hInstance;
  237.       pWndClass->style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  238.       pWndClass->lpfnWndProc = WinVnViewWndProc;
  239.  
  240.       bSuccess = RegisterClass(pWndClass);
  241.     }
  242.  
  243.    if(bSuccess) {
  244.       pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  245.       pWndClass->hIcon = LoadIcon(hInstance, (LPSTR) "wvart");
  246.       pWndClass->lpszMenuName = (LPSTR) "ArtMenu";
  247.       pWndClass->lpszClassName = (LPSTR) "WinVnArt";
  248.       pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  249.       pWndClass->hInstance = hInstance;
  250.       pWndClass->style = CS_HREDRAW | CS_VREDRAW;
  251.       pWndClass->lpfnWndProc = WinVnArtWndProc;
  252.  
  253.       bSuccess = RegisterClass(pWndClass);
  254.     }
  255.  
  256.    if(bSuccess) {
  257.       pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  258.       pWndClass->hIcon = LoadIcon(hInstance, (LPSTR) "wvpost");
  259.       pWndClass->lpszMenuName = (LPSTR) "PostMenu";
  260.       pWndClass->lpszClassName = (LPSTR) "WinVnPost";
  261.       pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  262.       pWndClass->hInstance = hInstance;
  263.       pWndClass->style = CS_HREDRAW | CS_VREDRAW;
  264.       pWndClass->lpfnWndProc = WinVnPostWndProc;
  265.  
  266.       bSuccess = RegisterClass(pWndClass);
  267.     }
  268.  
  269.    if(bSuccess) {
  270.       pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  271.       pWndClass->hIcon = LoadIcon(hInstance, (LPSTR) "wvmail");
  272.       pWndClass->lpszMenuName = (LPSTR) "MailMenu";
  273.       pWndClass->lpszClassName = (LPSTR) "WinVnMail";
  274.       pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  275.       pWndClass->hInstance = hInstance;
  276.       pWndClass->style = CS_HREDRAW | CS_VREDRAW;
  277.       pWndClass->lpfnWndProc = WinVnMailWndProc;
  278.  
  279.       bSuccess = RegisterClass(pWndClass);
  280.     }
  281.  
  282.     LocalUnlock(hMemory);
  283.     LocalFree(hMemory);
  284. #else
  285.    bSuccess = TRUE;
  286. #endif
  287.     return (bSuccess);
  288. }
  289.  
  290. /* --- Function MoreInit -----------------------------------------------
  291.  *
  292.  *    Finish up initializing the program.
  293.  *    I do as much initialization here as possible.  I'd rather
  294.  *    have code run after the main window is created (in WinVNInit),
  295.  *    so I have someplace to display error messages if necessary.
  296.  *
  297.  *    I read quite a few profile strings (from WIN.INI)
  298.  *    here and act appropriately (usually means setting a global variable).
  299.  *    I try to read as many as possible of the profile strings used by this
  300.  *    program here.
  301.  *    In particular, I do a bunch of font stuff here.
  302.  */
  303.  
  304. BOOL
  305. MoreInit()
  306. {
  307.    char szComName[10];
  308.    int retcode, j;
  309. #ifndef MAC
  310.    TEXTMETRIC  tmFontInfo;
  311.  
  312.    HDC hDC;
  313.  
  314.  
  315.    CheckView(hWndConf);        /* modify menu as necessary           */
  316.  
  317.    hDC = GetDC(hWndConf);
  318.    /* Unless user specified the system font, create a font as per
  319.     * the user's specifications.
  320.     */
  321.    if(FontSize) {
  322.       hFont = CreateFont(FontSize,
  323.          0,  /* width */
  324.          0,  /* escapement */
  325.          0,  /* orientation */
  326.          FontBold ? FW_BOLD : FW_MEDIUM,
  327.          0,  /* no italics */
  328.          0,  /* no underline */
  329.          0,  /* no strikeout */
  330.          0,
  331.          OUT_DEFAULT_PRECIS,
  332.          CLIP_DEFAULT_PRECIS,
  333.          0,  /* no PROOF_QUALITY */
  334.          0,
  335.          FontFace);
  336.    } else {
  337.       hFont = GetStockObject(SYSTEM_FONT);
  338.    }
  339.    ReleaseDC(hWndConf,hDC);
  340.  
  341.     /*  Get information about the font.  LineHeight and CharWidth
  342.      *  are pretty self-explanatory and the methods of determining these
  343.      *  are standard.  TopSpace and SideSpace are the top and left margins
  344.      *  in pixels; I compute them by a method I determined empirically.
  345.      */
  346.  
  347.    hDC = GetDC(hWndConf);
  348.    SelectObject(hDC,hFont);
  349.    GetTextMetrics(hDC,(LPTEXTMETRIC) &tmFontInfo);
  350.  
  351.    LineHeight = tmFontInfo.tmExternalLeading + tmFontInfo.tmHeight;
  352.    CharWidth  = tmFontInfo.tmAveCharWidth;
  353.    TopSpace = tmFontInfo.tmExternalLeading;
  354.    TopSpace = LineHeight / 4;
  355.    StartPen = TopSpace;
  356.    SideSpace = tmFontInfo.tmAveCharWidth/2;
  357.    ReleaseDC(hWndConf,hDC);
  358.  
  359. #else
  360.    BigClipRgn = NewRgn();
  361.    SetRectRgn(BigClipRgn,0,0,2000,2000);
  362.    SetWindowVars();
  363. #endif
  364.  
  365.    strcpy(SaveArtFileName,"");
  366.  
  367.    /* Initialize some document-related stuff.                        */
  368.  
  369.    ActiveGroupDoc = (TypDoc *)NULL;
  370.    ActiveArticleDoc = (TypDoc *)NULL;
  371.    for(j=0; j<MAXGROUPWNDS; j++) GroupDocs[j].InUse = FALSE;
  372.    for(j=0; j<MAXARTICLEWNDS; j++) ArticleDocs[j].InUse = FALSE;
  373.  
  374.    return retcode;
  375. }
  376.  
  377. #ifndef MAC
  378.  
  379. /*--- Function WinVnDoComm  -----------------------------------
  380.  *
  381.  *  Set communications parameters.
  382.  *
  383.  *  Entry    szComm         is a string equivalent to that on a MODE statement.
  384.  *                          E.g.,  "COM1:2400,n,8"
  385.  */
  386. int
  387. WinVnDoComm(szComm)
  388. char *szComm ;
  389. {
  390.     int retcode;
  391.     char mesbuf[60];
  392.  
  393.     if(retcode = BuildCommDCB(szComm,(DCB FAR *) &DCBComm)) {
  394.         sprintf(mesbuf,"BuildComm returned %d",retcode);
  395.         MessageBox(hWndConf,mesbuf,"Error building COM1 DCB",MB_OK|MB_ICONEXCLAMATION);
  396.     } else {
  397.         SetCommState((DCB FAR *) &DCBComm);
  398.     }
  399.     return (retcode);
  400. }
  401.  
  402. /*--- Function CommStrtoID --------------------------------------
  403.  *
  404.  *   Takes a communications string of the form given to the MODE command
  405.  *   and breaks it down to its constituent parts.
  406.  *
  407.  *   Entry    CommStr    is the string; e.g., "COM1:2400,n,8"
  408.  *
  409.  *   Exit     *Port      is the port (an IDD_* variable)
  410.  *            *Parity    is the parity/data bits infor (an IDD_* symbol)
  411.  *            szSpeed    is the speed, in character form
  412.  *            CommStr    has been converted to upper case.
  413.  *            Function value NULL if no error, else a pointer
  414.  *             to an error message.
  415.  */
  416. char *
  417. CommStrtoID(CommStr,Port,Parity,szSpeed)
  418. char *CommStr;
  419. int *Port, *Parity;
  420. char *szSpeed;
  421. {
  422.    char *ptr, *Speedptr;
  423.    int myPort;
  424.  
  425.    strupr(CommStr);
  426.    ptr = CommStr;
  427.  
  428.    while(*(ptr) == ' ') ptr++;
  429.  
  430.    /* Crack the "COMx" part of the string.                           */
  431.  
  432.    if(strncmp(ptr,"COM",3) != 0) return("Must be COM port");
  433.    ptr += 3;
  434.  
  435.    if(*ptr == '1') {
  436.       *Port = IDD_COM1;
  437.    } else if (*ptr == '2') {
  438.       *Port = IDD_COM2;
  439.    } else {
  440.       return("COM port must be 1 or 2");
  441.    }
  442.  
  443.    /* Crack the speed parameter.                                     */
  444.  
  445.    ptr += 2;
  446.    while(*ptr == ' ') ptr++;
  447.    for(Speedptr = szSpeed; isdigit(*ptr); *(Speedptr++) = *(ptr++));
  448.    *Speedptr = '\0';
  449.  
  450.    if(szSpeed == Speedptr) {
  451.       return("Non-numeric COM speed");
  452.    }
  453.  
  454.    while (isdigit(*ptr) || *ptr==' ' || *ptr==',') ptr++;
  455.  
  456.    /* Crack the parity parameter.                                    */
  457.  
  458.    if(*ptr == 'N') {
  459.       *Parity = IDD_8NONE;
  460.    } else if(*ptr == 'E') {
  461.       *Parity = IDD_7EVEN;
  462.    } else {
  463.       return("Bad parity");
  464.    }
  465.  
  466.    return (NULL);
  467. }
  468.  
  469. /*--- function MainLoopPass ---------------------------------------------
  470.  *
  471.  *    Do one pass of the main loop.
  472.  *
  473.  *    Entry
  474.  *
  475.  *    Exit     returns result of GetMessage()
  476.  */
  477. BOOL
  478. MainLoopPass()
  479. {
  480.    BOOL NoQuit;
  481.  
  482.    if(NoQuit = GetMessage(&MainMsg, NULL, NULL, NULL)) {
  483.       if(!TranslateAccelerator(MainMsg.hwnd,hAccel,&MainMsg)) {
  484.          TranslateMessage(&MainMsg);
  485.          DispatchMessage(&MainMsg);
  486.       }
  487.    }
  488.    return(NoQuit);
  489. }
  490. #endif
  491.